home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / metasploit / tools / memdump.c next >
C/C++ Source or Header  |  2006-06-30  |  5KB  |  247 lines

  1. /* skape <mmiller@hick.org */
  2.  
  3. /*
  4.  * dumps all the mapped memory segments in a running process
  5.  */
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <windows.h>
  9.  
  10. #define PAGE_SIZE 4096
  11.  
  12. typedef struct _MemoryRange
  13. {
  14.  
  15.     char                *base;
  16.     unsigned long       length;
  17.     char                *file;
  18.     struct _MemoryRange *next;
  19.  
  20. } MemoryRange;
  21.  
  22. BOOL createDumpDirectory(char *path);
  23. DWORD dumpSegments(HANDLE process, const char *dumpDirectory);
  24.  
  25. int main(int argc, char **argv)
  26. {
  27.     char *dumpDirectory = NULL;
  28.     HANDLE process = NULL;
  29.     DWORD pid = 0,
  30.         segments = 0;
  31.     int res = 1;
  32.  
  33.     do
  34.     {
  35.         // Validate arguments
  36.         if ((argc == 1) ||
  37.             (!(pid = atoi(argv[1]))))
  38.         {
  39.             printf("Usage: %s pid [dump directory]\n", argv[0]);
  40.             break;
  41.         }
  42.  
  43.         // If a dump directory is specified, use it, otherwise default 
  44.         // to the pid.
  45.         if (argc >= 3)
  46.             dumpDirectory = argv[2];
  47.         else
  48.             dumpDirectory = argv[1];
  49.  
  50.         // Create the dump directory (make sure it exists)
  51.         printf("[*] Creating dump directory...%s\n", dumpDirectory);
  52.  
  53.         if (!createDumpDirectory(dumpDirectory))
  54.         {
  55.             printf("[-] Creation failed, %.8x.\n", GetLastError());
  56.             break;
  57.         }
  58.  
  59.         // Attach to the process
  60.         printf("[*] Attaching to %lu...\n", pid);
  61.  
  62.         if (!(process = OpenProcess(PROCESS_VM_READ, FALSE, pid)))
  63.         {
  64.             printf("[-] Attach failed, %.8x.\n", GetLastError());
  65.             break;
  66.         }
  67.  
  68.         // Dump segments
  69.         printf("[*] Dumping segments...\n");
  70.  
  71.         if (!(segments = dumpSegments(process, dumpDirectory)))
  72.         {
  73.             printf("[-] Dump failed, %.8x.\n", GetLastError());
  74.             break;
  75.         }
  76.  
  77.         printf("[*] Dump completed successfully, %lu segments.\n", segments);
  78.  
  79.         res = 0;
  80.         
  81.     } while (0);
  82.  
  83.     if (process)
  84.         CloseHandle(process);
  85.  
  86.     return res;
  87. }
  88.  
  89. /*
  90.  * Create the directory specified by path, insuring that 
  91.  * all parents exist along the way.
  92.  *
  93.  * Just like MakeSureDirectoryPathExists, but portable.
  94.  */
  95. BOOL createDumpDirectory(char *path)
  96. {
  97.     char *slash = path;
  98.     BOOL res = TRUE;
  99.  
  100.     do
  101.     {
  102.         slash = strchr(slash, '\\');
  103.  
  104.         if (slash)
  105.             *slash = 0;
  106.  
  107.         if (!CreateDirectory(path, NULL))
  108.         {
  109.             if ((GetLastError() != ERROR_FILE_EXISTS) &&
  110.                 (GetLastError() != ERROR_ALREADY_EXISTS))
  111.             {
  112.                 res = FALSE;
  113.                 break;
  114.             }
  115.         }
  116.  
  117.         if (slash)
  118.             *slash++ = '\\';
  119.  
  120.     } while (slash);
  121.  
  122.     return res;
  123. }
  124.  
  125. /*
  126.  * Dump all mapped segments into the dump directory, one file per
  127.  * each segment.  Finally, create an index of all segments.
  128.  */
  129. DWORD dumpSegments(HANDLE process, const char *dumpDirectory)
  130. {
  131.     MemoryRange *ranges = NULL, 
  132.         *prevRange = NULL,
  133.         *currentRange = NULL;
  134.     char pbuf[PAGE_SIZE],
  135.         rangeFileName[256];
  136.     DWORD segments = 0, 
  137.         bytesRead = 0,
  138.         cycles = 0;
  139.     char *current = NULL;
  140.     FILE *rangeFd = NULL;
  141.  
  142.     // Enumerate page by page
  143.     for (current = 0;
  144.          ;
  145.          current += PAGE_SIZE, cycles++)
  146.  
  147.     {
  148.         // If we've wrapped, break out.
  149.         if (!current && cycles)
  150.             break;
  151.  
  152.         // Invalid page? Cool, reset current range.
  153.         if (!ReadProcessMemory(process, current, pbuf, 
  154.             sizeof(pbuf), &bytesRead))
  155.         {
  156.             if (currentRange)
  157.             {
  158.                 prevRange    = currentRange;
  159.                 currentRange = NULL;
  160.             }
  161.  
  162.             if (rangeFd)
  163.             {
  164.                 fclose(rangeFd);
  165.  
  166.                 rangeFd = NULL;
  167.             }
  168.  
  169.             continue;
  170.         }
  171.  
  172.         // If the current range is not valid, we've hit a new range.
  173.         if (!currentRange)
  174.         {
  175.             // Try to allocate storage for it, if we fail, bust out.
  176.             if (!(currentRange = (MemoryRange *)malloc(sizeof(MemoryRange))))
  177.             {
  178.                 printf("[-] Allocation failure\n");
  179.     
  180.                 segments = 0;
  181.     
  182.                 break;
  183.             }
  184.  
  185.             currentRange->base   = current;
  186.             currentRange->length = 0;
  187.             currentRange->next   = NULL;
  188.  
  189.             if (prevRange)
  190.                 prevRange->next = currentRange;
  191.             else
  192.                 ranges = currentRange;
  193.  
  194.             // Finally, open a file for this range
  195.             _snprintf(rangeFileName, sizeof(rangeFileName) - 1, "%s\\%.8x.rng",
  196.                 dumpDirectory, current);
  197.  
  198.             if (!(rangeFd = fopen(rangeFileName, "wb")))
  199.             {
  200.                 printf("[-] Could not open range file: %s\n", rangeFileName);
  201.  
  202.                 segments = 0;
  203.  
  204.                 break;
  205.             }
  206.  
  207.             // Duplicate the file name for ease of access later
  208.             currentRange->file = strdup(rangeFileName);
  209.  
  210.             // Increment the number of total segments
  211.             segments++;
  212.         }
  213.  
  214.         // Write to the range file
  215.         fwrite(pbuf, 1, bytesRead, rangeFd);
  216.  
  217.         currentRange->length += bytesRead;
  218.     }
  219.  
  220.     // Now that all the ranges are mapped, dump them to an index file
  221.     _snprintf(rangeFileName, sizeof(rangeFileName) - 1, "%s\\index.rng",
  222.         dumpDirectory);
  223.  
  224.     if ((rangeFd = fopen(rangeFileName, "w")))
  225.     {
  226.         char cwd[MAX_PATH];
  227.  
  228.         GetCurrentDirectory(sizeof(cwd), cwd);
  229.  
  230.         // Enumerate all of the ranges, dumping them into the index file
  231.         for (currentRange = ranges;
  232.              currentRange;
  233.              currentRange = currentRange->next)
  234.         {
  235.             fprintf(rangeFd, "%.8x;%lu;%s\\%s\n", 
  236.                 currentRange->base, currentRange->length, cwd,
  237.                 currentRange->file ? currentRange->file : "");
  238.         }
  239.  
  240.         fclose(rangeFd);
  241.     }
  242.     else
  243.         segments = 0;
  244.     
  245.     return segments;
  246. }
  247.